#!/usr/bin/env python3
# -*- coding: utf-8 -*-
' main entry '
__author__ = 'pingwu you'


def demo_help():    
    from urllib import request,parse
    #GET请求
    with request.urlopen('https://www.baidu.com/') as f:
        data = f.read()
        print('Status:', f.status, f.reason)
        for k, v in f.getheaders():
            print('%s: %s' % (k, v))
        print('Data:', data.decode('utf-8'))
    """
    如果要模拟浏览器完成特定功能，需要把请求伪装成浏览器。
    伪装的方法是先监控浏览器发出的请求，再根据浏览器的请求头来伪装，User-Agent头就是用来标识浏览器的。
    """
    req = request.Request('https://www.baidu.com/')
    req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25')
    with request.urlopen(req) as f:
        print('Status:', f.status, f.reason)
        for k, v in f.getheaders():
            print('%s: %s' % (k, v))
        print('Data:', f.read(1024).decode('utf-8'))

    """
    充分模拟，跨域，origin / refer 都统统模拟
    """
    print('Login to weibo.cn...')
    email = input('Email: ')
    passwd = input('Password: ')
    login_data = parse.urlencode([
        ('username', email),
        ('password', passwd),
        ('entry', 'mweibo'),
        ('client_id', ''),
        ('savestate', '1'),
        ('ec', ''),
        ('pagerefer', 'https://passport.weibo.cn/signin/welcome?entry=mweibo&r=http%3A%2F%2Fm.weibo.cn%2F')
    ])

    req = request.Request('https://passport.weibo.cn/sso/login')
    req.add_header('Origin', 'https://passport.weibo.cn')
    req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25')
    req.add_header('Referer', 'https://passport.weibo.cn/signin/login?entry=mweibo&res=wel&wm=3349&r=http%3A%2F%2Fm.weibo.cn%2F')

    with request.urlopen(req, data=login_data.encode('utf-8')) as f:
        print('Status:', f.status, f.reason)
        for k, v in f.getheaders():
            print('%s: %s' % (k, v))
        print('Data:', f.read().decode('utf-8'))

"""
HTML本质上是XML的子集，但是HTML的语法没有XML那么严格，所以不能用标准的DOM或SAX来解析HTML。
Python提供了HTMLParser来非常方便地解析HTML
"""
from html.parser import HTMLParser
from html.entities import name2codepoint
class MyHTMLParser(HTMLParser):
    def handle_starttag(self, tag, attrs):
        print('<%s>' % tag)
    def handle_endtag(self, tag):
        print('</%s>' % tag)
    def handle_startendtag(self, tag, attrs):
        print('<%s/>' % tag)
    def handle_data(self, data):
        print(data)
    def handle_comment(self, data):
        print('<!--', data, '-->')
    def handle_entityref(self, name):
        print('&%s;' % name)
    def handle_charref(self, name):
        print('&#%s;' % name)

def html_parse():
    parser = MyHTMLParser()
    print("--------------开始解释html啦-----------------")
    parser.feed('''<html>
    <head></head>
    <body>
    <!-- test html parser -->
        <p>Some <a href=\"#\">html</a>中国 &#1234;&#1234;HTML&nbsp;tutorial...<br>END</p>
    </body></html>''')
    print("--------------结束解释html啦-----------------")

#更加便捷强大的webreq
def requests_help():
    import requests    
    cs = {'token': '12345', 'status': 'working'}
    r = requests.get('https://www.douban.com/search',
        #headers={'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit'},
        params={'q': 'python', 'cat': '1001'},
        cookies=cs)
    print(r.__dict__)
    print(r.encoding)
    #无论响应是文本还是二进制内容，我们都可以用content属性获得bytes对象
    # r.content
    #对于特定类型的响应，例如JSON，可以直接获取
    #r.json()

    #requests默认使用application/x-www-form-urlencoded对POST数据编码。如果要传递JSON数据，可以直接传入json参数：
    r = requests.post('https://accounts.douban.com/login', data={'form_email': 'abc@example.com', 'form_password': '123456'})
    #requests对Cookie做了特殊处理，使得我们不必解析Cookie就可以轻松获取指定的Cookie
    #r.cookies['ts']

    params = {'key': 'value'}
    r = requests.post('https://accounts.douban.com/login', json=params) # 内部自动序列化为JSON

    # upload_files = {'file': open('report.xls', 'rb')}
    # r = requests.post('https://accounts.douban.com/login', files=upload_files)

    #在读取文件时，注意务必使用'rb'即二进制模式读取，这样获取的bytes长度才是文件的长度。